﻿using com_errorLib;
using com_realtime_playerLib;
using com_session_ptzctrlLib;
using com_sessionLib;
using Infrastructure.Lib.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HxhtCapture.Job
{
    public partial class Megaeyes
    {
        /// <summary>
        /// 云台预置点调用
        /// </summary>
        private void gotoPresetAndCapture(Camera camera)
        {
            try
            {
                var cfg_str = "";
                cfg_str += "<Source type=\"access\">";
                cfg_str += "<Camera naming=\"" + camera.Naming + "\" name=\"" + camera.Title + "\" />";
                cfg_str += "<Version value=\"1\" />";
                cfg_str += "<Account naming=\"" + _account_naming + "\" name=\"" + _account + "\" privilege=\"" + _account_level + "\" sessionid=\"" + _session_id + "\" />";
                cfg_str += "<Center ip=\"" + _j2ee_ip + "\" port=\"" + _j2ee_port + "\" />";
                cfg_str += "<Access ip=\"" + _center_ip + "\" port=\"" + _center_port + "\" />";
                cfg_str += "</Source>";

                HxhtSessionPtzCtrlClass hxhtSessionPtzCtrl = new HxhtSessionPtzCtrlClass();

                hxhtSessionPtzCtrl.OnAccessReturn += (nOperatorType, nError1, nParam, szParamEx) =>
                {
                    //logger.InfoFormat("PtzCtrl: OperatorType:{0},Error:{1},Param:{2},ParamEx:{3}", nOperatorType, nError1, nParam, szParamEx);

                    if (nOperatorType == 0)
                    {
                        //var presetId = hxhtSessionPtzCtrl.GetPresetID(32);

                        //Console.WriteLine("GetPresetID:{0}", presetId);

                        //if (presetId > 0)
                        //{
                        var gotoResult = hxhtSessionPtzCtrl.GotoPreset(32, 128);

                        logger.InfoFormat("GotoResult:{0}", gotoResult);
                        if (gotoResult > 0)
                        {
                            this.Login();
                        }
                        //}
                    }

                    if (nOperatorType == 19)
                    {
                        System.Threading.Thread.Sleep(1000);

                        try
                        {
                            captureJpg(cfg_str, camera.Stcd);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.ToString());
                        }
                    }

                };

                var setNameing = hxhtSessionPtzCtrl.SetNaming(camera.Naming);

                //Console.WriteLine("SetNameing:{0}", setNameing);

                var queryVersion = hxhtSessionPtzCtrl.QueryVersion();

                //Console.WriteLine("QueryVersion:{0}", queryVersion);
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString());
                this.Login();
            }
        }

        /// <summary>
        /// 抓图
        /// </summary>
        /// <param name="cfg_str"></param>
        private void captureJpg(string cfg_str, string stcd)
        {
            HxhtRealtimePlayerComClass hxhtRealtimePlayerCom = new HxhtRealtimePlayerComClass();

            try
            {
                var initRealPlayerResult = hxhtRealtimePlayerCom.Init(cfg_str);

                logger.InfoFormat("InitRealPlayerResult:{0}", initRealPlayerResult);

                var connectResult = hxhtRealtimePlayerCom.Connect();

                logger.InfoFormat("ConnectResult:{0}", connectResult);

                if (connectResult > 0)
                {
                    this.Login();
                }

                int tryTimes = 0;

                var picExt = hxhtRealtimePlayerCom.GetPictureExt();

                var tmpPath = JpgPath.TempFileNameWithoutExt + "." + picExt;
                var saveFile = JpgPath.GenerateFilePath(stcd);
                var snapFile = (picExt == "bmp") ? tmpPath : saveFile;

                while (true)
                {
                    var status = hxhtRealtimePlayerCom.GetStatus();

                    logger.InfoFormat("Player Status:{0}", status);

                    //if (status == 1)
                    //{
                    //    tryTimes++;
                    //    if (tryTimes >= 3) break;
                    //    break;
                    //}

                    if (status == 5)
                    {
                        //logger.InfoFormat("PicExt:{0}", picExt);

                        var snapShotResult = hxhtRealtimePlayerCom.Snapshot(snapFile, true);

                        logger.InfoFormat("SnapShotResult:{0}", snapShotResult);

                        if (snapShotResult == 0)
                        {
                            if (picExt == "bmp")
                            {
                                using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(snapFile))
                                {
                                    bmp.Save(saveFile, System.Drawing.Imaging.ImageFormat.Jpeg);
                                }
                                FileHelper.DeleteFile(snapFile);
                            }
                            break;
                        }
                        else
                        {
                            HxhtErrorClass hxhtError = new HxhtErrorClass();
                            logger.ErrorFormat(hxhtError.FormatError(snapShotResult, false));

                            tryTimes++;
                            if (tryTimes >= 5) break;
                            System.Threading.Thread.Sleep(200);
                        }
                    }
                    else
                    {
                        tryTimes++;
                        if (tryTimes >= 10) break;
                    }

                    System.Threading.Thread.Sleep(300);
                }

                //hxhtRealtimePlayerCom.Stop();
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString());
                this.Login();
            }
            finally
            {
                hxhtRealtimePlayerCom.Stop();
            }


        }

        public void LogOut()
        {
            if (null != _hxhtSession)
                _hxhtSession.Logout();
        }

        public void Login()
        {
            _hxhtSession = new HxhtSessionClass();

            _hxhtSession.OnStatusChanged += (nStatus, nError) =>
            {
                logger.Info(string.Format("HxhtSession Status:{0} Error:{1}", nStatus, nError));

                if (nStatus == 4)
                {
                    //连接被关闭，重新登录
                    if (450971566080 == nError)
                    {
                        _hxhtSession.Logout();
                        _hxhtSession.Login();
                        return;
                    }

                    _account_naming = _hxhtSession.GetUserNaming();
                    _account = _config.Name;
                    _account_level = 0;
                    _session_id = _hxhtSession.GetSessionID();
                    _j2ee_ip = _config.Host;
                    _j2ee_port = _config.Port;
                    _center_ip = _hxhtSession.GetAccessIP();
                    _center_port = _hxhtSession.GetAccessPort();

                    _isLogined = true;
                }
            };

            var initResult = _hxhtSession.Init(_initXml, "");
            var loginResult = _hxhtSession.Login();
        }

        public void CaptureAllJpeg()
        {
            //_config.CameraList.ForEach(camera =>
            //{
            //    gotoPresetAndCapture(camera);
            //});

            Parallel.ForEach(_config.CameraList, camera =>
           {
               gotoPresetAndCapture(camera);
           });
        }

        public async Task<Megaeyes> WaitForLogin()
        {
            while (!_isLogined)
            {
                await Task.Delay(100);
            }

            return this;
        }

    }
}
